import { BehaviorInfo, SDKConfig } from '../types';
import { 
  getCurrentUrl, 
  getElementSelector, 
  getElementText, 
  shouldSample,
  throttle,
  debounce 
} from '../utils';

export class BehaviorMonitor {
  private config: SDKConfig;
  private behaviorHandler: (behavior: BehaviorInfo) => void;
  private isInitialized = false;

  constructor(config: SDKConfig, behaviorHandler: (behavior: BehaviorInfo) => void) {
    this.config = config;
    this.behaviorHandler = behaviorHandler;
  }

  // 初始化行为监控
  public init(): void {
    if (this.isInitialized) {
      return;
    }

    this.isInitialized = true;

    // 监听点击事件
    this.setupClickHandler();
    
    // 监听滚动事件
    this.setupScrollHandler();
    
    // 监听输入事件
    this.setupInputHandler();
    
    // 监听页面导航
    this.setupNavigationHandler();
  }

  // 设置点击事件处理器
  private setupClickHandler(): void {
    const throttledClickHandler = throttle((event: MouseEvent) => {
      if (!shouldSample(this.config.sampleRate)) {
        return;
      }

      const target = event.target as Element;
      if (!target) return;

      const behaviorInfo: BehaviorInfo = {
        type: 'click',
        selector: getElementSelector(target),
        text: getElementText(target),
        url: getCurrentUrl(),
        timestamp: Date.now(),
        extra: {
          x: event.clientX,
          y: event.clientY,
          button: event.button,
          ctrlKey: event.ctrlKey,
          shiftKey: event.shiftKey,
          altKey: event.altKey,
          metaKey: event.metaKey
        }
      };

      this.behaviorHandler(behaviorInfo);
    }, 1000); // 1秒内只记录一次点击

    document.addEventListener('click', throttledClickHandler, true);
  }

  // 设置滚动事件处理器
  private setupScrollHandler(): void {
    const debouncedScrollHandler = debounce((event: Event) => {
      if (!shouldSample(this.config.sampleRate)) {
        return;
      }

      const target = event.target as Element;
      if (!target) return;

      const behaviorInfo: BehaviorInfo = {
        type: 'scroll',
        selector: getElementSelector(target),
        url: getCurrentUrl(),
        timestamp: Date.now(),
        extra: {
          scrollTop: (target as HTMLElement).scrollTop || 0,
          scrollLeft: (target as HTMLElement).scrollLeft || 0,
          scrollHeight: (target as HTMLElement).scrollHeight || 0,
          scrollWidth: (target as HTMLElement).scrollWidth || 0,
          clientHeight: (target as HTMLElement).clientHeight || 0,
          clientWidth: (target as HTMLElement).clientWidth || 0
        }
      };

      this.behaviorHandler(behaviorInfo);
    }, 500); // 500ms防抖

    document.addEventListener('scroll', debouncedScrollHandler, true);
  }

  // 设置输入事件处理器
  private setupInputHandler(): void {
    const debouncedInputHandler = debounce((event: Event) => {
      if (!shouldSample(this.config.sampleRate)) {
        return;
      }

      const target = event.target as HTMLInputElement | HTMLTextAreaElement;
      if (!target) return;

      const behaviorInfo: BehaviorInfo = {
        type: 'input',
        selector: getElementSelector(target),
        text: target.value ? target.value.substring(0, 50) : '', // 只记录前50个字符
        url: getCurrentUrl(),
        timestamp: Date.now(),
        extra: {
          inputType: target.type,
          placeholder: target.placeholder || '',
          maxLength: target.maxLength || -1,
          valueLength: target.value.length
        }
      };

      this.behaviorHandler(behaviorInfo);
    }, 1000); // 1秒防抖

    document.addEventListener('input', debouncedInputHandler, true);
  }

  // 设置页面导航处理器
  private setupNavigationHandler(): void {
    // 监听页面跳转
    const originalPushState = history.pushState;
    const originalReplaceState = history.replaceState;

    history.pushState = function(...args: any[]) {
      const result = originalPushState.apply(this, args);
      
      if (shouldSample(this.config.sampleRate)) {
        const behaviorInfo: BehaviorInfo = {
          type: 'navigation',
          url: getCurrentUrl(),
          timestamp: Date.now(),
          extra: {
            navigationType: 'pushState',
            state: args[0],
            title: args[1],
            url: args[2]
          }
        };

        this.behaviorHandler(behaviorInfo);
      }
      
      return result;
    };

    history.replaceState = function(...args: any[]) {
      const result = originalReplaceState.apply(this, args);
      
      if (shouldSample(this.config.sampleRate)) {
        const behaviorInfo: BehaviorInfo = {
          type: 'navigation',
          url: getCurrentUrl(),
          timestamp: Date.now(),
          extra: {
            navigationType: 'replaceState',
            state: args[0],
            title: args[1],
            url: args[2]
          }
        };

        this.behaviorHandler(behaviorInfo);
      }
      
      return result;
    };

    // 监听浏览器前进后退
    window.addEventListener('popstate', (event) => {
      if (!shouldSample(this.config.sampleRate)) {
        return;
      }

      const behaviorInfo: BehaviorInfo = {
        type: 'navigation',
        url: getCurrentUrl(),
        timestamp: Date.now(),
        extra: {
          navigationType: 'popstate',
          state: event.state
        }
      };

      this.behaviorHandler(behaviorInfo);
    });
  }

  // 手动上报用户行为
  public reportBehavior(behavior: BehaviorInfo): void {
    if (!shouldSample(this.config.sampleRate)) {
      return;
    }

    this.behaviorHandler(behavior);
  }

  // 销毁行为监控器
  public destroy(): void {
    this.isInitialized = false;
    // 移除事件监听器
    document.removeEventListener('click', this.setupClickHandler);
    document.removeEventListener('scroll', this.setupScrollHandler);
    document.removeEventListener('input', this.setupInputHandler);
    window.removeEventListener('popstate', this.setupNavigationHandler);
  }
} 